package com.proton.carepatchtemp.application;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.sdk.android.oss.OSSClient;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.apkfuns.logutils.LogUtils;
import com.baidu.mobstat.StatService;
import com.proton.carepatchtemp.BuildConfig;
import com.proton.carepatchtemp.R;
import com.proton.carepatchtemp.constant.Extras;
import com.proton.carepatchtemp.constant.Settings;
import com.proton.carepatchtemp.database.AliyunToken;
import com.proton.carepatchtemp.database.TestManager;
import com.proton.carepatchtemp.database.daomanager.GreenDaoManager;
import com.proton.carepatchtemp.database.gen.DaoMaster;
import com.proton.carepatchtemp.database.table.FirmWare;
import com.proton.carepatchtemp.database.table.User;
import com.proton.carepatchtemp.listener.TaxiListener;
import com.proton.carepatchtemp.login.activity.LoginFirstActivity;
import com.proton.carepatchtemp.utils.ACache;
import com.proton.carepatchtemp.utils.ApiUtils;
import com.proton.carepatchtemp.utils.AppInitUtils;
import com.proton.carepatchtemp.utils.BleHelper;
import com.proton.carepatchtemp.utils.FrescoUtils;
import com.proton.carepatchtemp.utils.GsonUtils;
import com.proton.carepatchtemp.utils.JudgeUtils;
import com.proton.carepatchtemp.utils.Log.BuglyUtils;
import com.proton.carepatchtemp.utils.SAppUtils;
import com.proton.carepatchtemp.utils.SpUtils;
import com.proton.carepatchtemp.utils.TastyUtils;
import com.proton.carepatchtemp.utils.UmengUtils;
import com.proton.carepatchtemp.utils.net.oss.OSSUtils;
import com.sdsmdg.tastytoast.TastyToast;
import com.squareup.leakcanary.LeakCanary;
import com.taobao.sophix.SophixManager;
import com.wms.utils.CommonUtils;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.chat2.Chat;
import org.jivesoftware.smack.chat2.ChatManager;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by Api on 2016/9/21.
 */

public class VCare extends Application {

    public static final String TAG = "VCare";
    public static boolean hasCheckFloatPermission;
    /**
     * 是否国际版本
     */
    public static boolean isInternal = BuildConfig.IS_INTERNAL;
    private static VCare mInstance;
    private static volatile ACache sInst = null;  // <<< 这里添加了 volatile
    public int localVersion = 1;
    public String cookie = "";
    public RequestQueue mRequestQueue = null;
    public ExecutorService mCachePool = null;
    //XMPP消息发送线程池
    public ExecutorService mMsgPool = null;
    public ExecutorService mCacheDataPool = null;
    public boolean supportBle = false;
    //  XMPP
    public XMPPTCPConnection mXmpp;
    public TaxiListener connectionListener;
    public boolean imConnected = true;
    public boolean need = true;
    public AliyunToken aliyunToken;
    public OSSClient oss;
    //  需要固件升级的设备数量
    public int needUpdate = 0;
    private boolean isOnceComplete;
    private boolean authflag;
    private SharedPreferences mPreferences;
    private User cacheUser = null;
    //固件升级信息
    private FirmWare mFirmWare;
    private String version;
    private String systemInfo;

    public static VCare get() {
        return mInstance;
    }

    public static ACache getACacheInstance() {
        ACache inst = sInst;  // <<< 在这里创建临时变量
        if (inst == null) {
            synchronized (ACache.class) {
                inst = sInst;
                if (inst == null) {
                    inst = new ACache(mInstance.getCacheDir(), Settings.MAX_SIZE, Settings.MAX_COUNT);
                    sInst = inst;
                }
            }
        }
        return inst;  // <<< 注意这里返回的是临时变量
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = VCare.this;
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .build());
        }
        //数据库初始化
        GreenDaoManager.get();
        AppInitUtils.initDebug(mInstance);
        if (SAppUtils.isMainProcess(VCare.get())) {
            supportBle = BleHelper.supportBle(mInstance);
            if (!supportBle) {
                TastyUtils.makeText(getApplicationContext(), R.string.ble_not_supported, TastyToast.LENGTH_LONG, TastyToast.ERROR);
            }
        }
        mPreferences = SpUtils.getSp();  //初始化SharedPreferences
        authflag = hasToken();
        UmengUtils.initUmeng();
        FrescoUtils.initFreso();
        BuglyUtils.init(this);
        OSSUtils.initOss();
        if (!isInternal) {
            StatService.setAppKey("f5f6af6091");
        } else {
            StatService.setAppKey("0cd528d30d");
        }
        StatService.setDebugOn(BuildConfig.DEBUG);
        if (BuildConfig.DEBUG) {
            initLeakCanary();
        }
    }

    private void initLeakCanary() {
        if (LeakCanary.isInAnalyzerProcess(this)) {
            return;
        }
        LeakCanary.install(this);
    }

    private boolean hasToken() {
        String token = mPreferences.getString(Extras.TOKEN, "");
        cookie = token;
        return !TextUtils.isEmpty(token);
    }

    public RequestQueue getRequestQueue() {
        if (null == mRequestQueue) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }

    public long getUid() {
        return SpUtils.getLong("uid", 0);
    }

    public User getUser() {
        if (cacheUser != null) {
            return cacheUser;
        }

        User userA = GsonUtils.getGson().fromJson(String.valueOf(SpUtils.getString(SpUtils.USER_OBJ, null)), User.class);

        if (userA == null) {
            userA = new User();
        } else {
            cacheUser = userA;
        }
        //无SpUser 返回空user；
        return userA;
    }

    public final void setupSessionCookie(String cookieStr, String token, User user, String userStr) {
        authflag = true;
        cacheUser = user;
        cookie = cookieStr;
        SpUtils.setToken(token);
        SpUtils.saveLong("uid",user.getId());
        SharedPreferences.Editor prefEditor = mPreferences.edit();
        prefEditor.putString(SpUtils.USER_OBJ, userStr);
        prefEditor.apply();
    }

    public String getToken() {
        return SpUtils.getToken();
    }

    public boolean isAuthflag() {
        return authflag;
    }

    public final void addSessionCookie(Map<String, String> headers, long uid, String token) {
        headers.put(Extras.APITOKEN, token);
        headers.put(Extras.APIUID, String.valueOf(uid));
        headers.put("version", VCare.get().getVersion());
        headers.put("model", VCare.get().getSystemInfo());
        LogUtils.e(headers);
    }

    public final void addSessionCookie(Map<String, String> headers) {
        String token = SpUtils.getToken();
        if (!TextUtils.isEmpty(token)) authflag = true;
        headers.put(Extras.APITOKEN, token);
        headers.put(Extras.APIUID, getUidStr());
        headers.put("version", VCare.get().getVersion());
        headers.put("model", VCare.get().getSystemInfo());
//        LogUtils.e(headers);
    }

    public String getUidStr() {
//        LogUtils.i("getUidStr", "getUidStr");
//        LogUtils.e(TAG, getUser());
        return String.valueOf(getUid());
    }

    public void dealNeedLogin(boolean b) {
        LogUtils.e("dealNeedLogin " + "in");
//        if (dealUnAuth) return;
//        LogUtils.e("dealNeedLogin " + "realin");
//        dealUnAuth = true;
//        startActivity(new Intent(this, LoginActvt.class).putExtra(Extras.KILLALL, true));
//        TastyUtils.makeTextShort("您的账号已在另外一台设备登录\n请重新登录",TastyToast.DEFAULT);
        VCare.get().logout();
//        Intent intent = VCare.get().getPackageManager().getLaunchIntentForPackage(VCare.get().getPackageName());
//        intent = new Intent(this, LoginAuthActivity.class).putExtra(Extras.KILLALL, true);
//        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        VCare.get().startActivity(intent);
    }

    @SuppressLint("CommitPrefEdits")
    public void logout() {
        authflag = false;
        clearSharePreference();
        //取消所有网络请求
//        if (null != getRequestQueue()) {
//            getRequestQueue().cancelAll(null);
//        }
//        Iterator iterator = actvts.iterator();
//        WeakReference<Activity> activity = null;
//
//        while (iterator.hasNext()){
//            activity = (WeakReference<Activity>) iterator.next();
//            if (null != activity){
//                activity.get().finish();
//            }
//        }

        if (!BuildConfig.DEBUG) {
            SophixManager.getInstance().queryAndLoadNewPatch();
        }

        SophixStubApplication.appExit();

        TestManager.container.clear();
        //删除之后需要重新创建，否则插入数据报错
        DaoMaster.dropAllTables(GreenDaoManager.get().getmDaoMaster().getDatabase(), true);
        DaoMaster.createAllTables(GreenDaoManager.get().getmDaoMaster().getDatabase(), true);
        restartApplication();
    }

//    public void removeActvts(BaseActivity baseActivity) {
//        List list=new ArrayList();
//        for(WeakReference<Activity> actvt:actvts){
//            if(null!=actvt.get()){
//                if(actvt.get()==baseActivity){
//                    list.add(actvt);
//                }
//            }
//        }
//        try {
//            actvts.removeAll(list);
//        }catch (Throwable e){
//            LogUtils.e(e);
//        }
//    }

    public void restartApplication() {
        final Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
    }

    //清空sharePreference内容
    private void clearSharePreference() {
        cacheUser = null;
        cookie = "";
        SpUtils.cToken = null;
        SpUtils.remove(Extras.TOKEN);
        SpUtils.remove(SpUtils.USER_OBJ);
    }

    public ExecutorService getCachePool() {
        if (null == mCachePool) {
            mCachePool = Executors.newCachedThreadPool();
        }
        return mCachePool;
    }

    public XMPPTCPConnection getXmppConnection() {
        try {
            if (mXmpp != null) {
                if (mXmpp.isConnected()) {
                    return mXmpp;
                } else {
                    try {
                        mXmpp.connect();
                    } catch (SmackException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (XMPPException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return mXmpp;
                }
            }
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }

        XMPPTCPConnectionConfiguration.Builder config;

        config = XMPPTCPConnectionConfiguration.builder();
        LogUtils.e("create config");
        config.setHost(ApiUtils.imDomain());              //设置openfire主机IP
        config.setPort(ApiUtils.imDomainPort());                   //设置端口号：默认5222
        try {
            config.setXmppDomain(ApiUtils.imDomain());    //XMpp服务器名称
        } catch (XmppStringprepException e) {
            LogUtils.e(e);
        }
        config.allowEmptyOrNullUsernames();
        config.setKeystoreType("AndroidCAPath");
        config.setKeystorePath(null);
        config.setUsernameAndPassword(null, null);    //设置用户名与密码
        config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);      //禁用SSL连接
        config.setSendPresence(false);
        config.setDebuggerEnabled(true);
        config.setCompressionEnabled(false);

        mXmpp = new XMPPTCPConnection(config.build());
//        try {
//            mXmpp.connect();
//        } catch (Exception e) {
//            LogUtils.e(e);
//        }
        return mXmpp;
    }

    public void closeConnection() {
        try {
            if (getTaxiListener() != null) {
                if (mXmpp != null) {
                    mXmpp.removeConnectionListener(getTaxiListener());
                }
            }
        } catch (NullPointerException ignored) {
        }
    }

    public ConnectionListener getTaxiListener() {
        if (connectionListener == null) {
            connectionListener = new TaxiListener();
        }
        return connectionListener;
    }

    public Chat getChatroom(String uid) {
        XMPPConnection con = getXmppConnection();
        if (con != null) {
            ChatManager manager = ChatManager.getInstanceFor(con);
            Chat chat = null;

            try {
                chat = manager.chatWith(JidCreate.entityBareFrom("user" + uid + "@" + ApiUtils.imDomain()));
            } catch (XmppStringprepException e) {
                e.printStackTrace();
            }

            return chat;
        }
        return null;
    }

    public String getXmppAct() {
        return "user" + getUid() + "@" + ApiUtils.imDomain();
    }

    public boolean isOnceComplete() {
        return isOnceComplete;
    }

    public void setOnceComplete(boolean onceComplete) {
        isOnceComplete = onceComplete;
    }

    /**
     * public String getUmtoken() {
     * return umtoken;
     * }
     * <p>
     * public void setUmtoken(String umtoken) {
     * this.umtoken = umtoken;
     * }
     * /**
     * 结束指定类名的Activity
     */
    public void finishActivity(Class<?> cls) {
        SophixStubApplication.finishActivity(cls);
    }

    public void closeAllExpect(Activity register1Actvt) {
        for (Activity activity : SophixStubApplication.mActivitys) {
            if (activity != null) {
                if (activity instanceof LoginFirstActivity && !JudgeUtils.sameActvt(register1Actvt, activity)) {
                    activity.finish();
                }
            }
        }
    }

    public ExecutorService getMsgPool() {
        if (mMsgPool == null) {
            mMsgPool = Executors.newFixedThreadPool(100);
        }
        return mMsgPool;
    }

    public ExecutorService getCacheDataPool() {
        if (mCacheDataPool == null) {
            mCacheDataPool = Executors.newSingleThreadExecutor();
        }
        return mCacheDataPool;
    }

    public FirmWare getFirmWare() {
        return mFirmWare;
    }

    public void setFirmWare(FirmWare firmWare) {
        mFirmWare = firmWare;
    }

    public String getVersion() {
        if (TextUtils.isEmpty(version)) {
            version = CommonUtils.getAppVersion(VCare.get()) + "&" + CommonUtils.getAppVersionCode(VCare.get());
        }
        return version;
    }

    public String getSystemInfo() {
        if (TextUtils.isEmpty(systemInfo)) {
            systemInfo = android.os.Build.MODEL + "&" + android.os.Build.VERSION.RELEASE;
        }
        return systemInfo;
    }
}
